//
// Prob.cpp for math 202 in /home/druart_p/Work/math/my-math-epi/202
//
// Made by pierrick druart
// Login   <druart_p@epitech.net>
//
// Started on  Tue Feb 28 09:21:14 2012 pierrick druart
// Last update Thu May 31 15:19:54 2012 pierrick druart
//

#include <list>

#include "Prob.hpp"
#include "Calc.hh"

// CONSTRUCTOR & DESTRUCTOR

Prob::Prob(int & ac, char **av)
{
  std::istringstream	iss(av[1]);

  iss >> this->val_;
  this->ac = ac;
  this->av = av;
  if (ac > 4)
    throw my_exception_help();
  verif_arg(av);
  if (this->val_ <= 4 && this->val_ > 0)
    {
      this->func_[1] = &Prob::option1;
      this->func_[2] = &Prob::option2;
      this->func_[3] = &Prob::option3;
      this->func_[4] = &Prob::option4;
    }
  else
    throw my_exception_arg(av[1]);
  exec();
}

Prob::~Prob()
{
  this->func_.clear();
}

// EXECUTION

void	Prob::exec()
{
  (this->*func_[this->val_])();
}

// OPTION

void	Prob::option1()
{
  if (this->ac != 4)
    throw my_exception_help();
  std::istringstream	iss(this->av[2]);
  std::istringstream	iss2(this->av[3]);
  int       		n;
  int		      	p;

  iss >> n;
  iss2 >> p;
  if (n > 100 || n < p || n < 0 || p < 1)
    throw my_exception_help();
  Calc	calcul;

  std::cout << std::fixed << std::setprecision(0)<< calcul.loiBinomiale((double)n, (double)p) << std::endl;
}

void	Prob::option2()
{
  if (this->ac != 4)
    throw my_exception_help();
  std::istringstream	iss(this->av[2]);
  std::istringstream	iss2(this->av[3]);
  std::list<double>	value;
  Calc			calcul;
  int       		n;
  double	       	p;
  int             	i;

  iss >> n;
  iss2 >> p;
  if (n > (LENGTH - 60) || n < p || n < 0 || p == 0 )
    throw my_exception_help();
  for(i = 0; i <= n; i++)
    value.push_back(calcul.loiDiscreteBinomiale((double)n ,p ,(double)i));
  QApplication		app(this->ac, this->av);
  Surface	       	surface(this->av, value);

  surface.show();
  app.exec();
}

void	Prob::option3()
{
  if (this->ac != 3)
    throw my_exception_help();
  std::istringstream	iss(this->av[2]);
  std::list<double>	value;
  Calc			calcul;
  double       		n;
  int		       	i;

  iss >> n;
  for(i = 0; i <= 100; i++)
    value.push_back(calcul.loiPoisson(n ,i));
  QApplication		app(this->ac, this->av);
  Surface	       	surface(this->av, value);

  surface.show();
  app.exec();
}

void	Prob::option4()
{
  if (this->ac != 2)
    throw my_exception_help();
  std::list<double>	value;
  std::list<double>	value2;
  Calc			calcul;
  int             	i;

  for(i = 0; i <= 100; i++)
    value.push_back(calcul.loiDiscreteBinomiale((double)100 ,0.1 ,(double)i));
  for(i = 0; i <= 100; i++)
    value2.push_back(calcul.loiPoisson(10 ,i));
  QApplication		app(this->ac, this->av);
  Surface	       	surface(this->av, "100", value, value2);

  surface.show();
  app.exec();
}

// CHECK ARG

void	Prob::verif_arg(char **av)
{
  for (int i = 2;av[i]; i++)
    {
      for (int j = 0;av[i][j]; j++)
	{
	  if (av[i][j] < '0' || av[i][j] > '9')
	    if (av[i][j] != '.')
	      throw my_exception_arg(av[i]);
	}
    }

}
